這篇我們來實作主要移動棋子的方法move(),以及發生移動事件後會使用到的其他方法,接著實作關於士兵升變的方法
首先判斷遊戲是否結束,再通過一些局面的判斷,然後產生棋譜資料,再將修改後的棋盤資料上傳到資料庫,最後初始化本回合暫存的所有變數
public void move(){
new Thread(() -> {
// 判斷遊戲是否結束
if(!isGameFinish()){
// 如果有王車易位,則修改指定格的棋子
isCastling();
// 處理兵的特殊情況
disposePawn();
// 產生棋譜資料
moveData(String.valueOf(playerChessboardData.getStringBoardData(startChessman))
,String.valueOf(playerChessboardData.getStringBoardData(stopChessman)));
// 判斷是否可升變
isPromotion();
// 修改棋盤資料,將目標格棋子改為原起始格棋子,原起始格棋子改為空格
chessboardData.put(String.valueOf(playerChessboardData.getStringBoardData(stopChessman)),String.valueOf(chessboardData.get(playerChessboardData.getStringBoardData(startChessman))));
chessboardData.put(String.valueOf(playerChessboardData.getStringBoardData(startChessman))," ");
dbp.uploadData(roomKey,"PawnMove1",pawnMove1);
// 上傳棋盤資料
if(isPromotion == false){
chessmanMoveData.put(String.valueOf(turn),moveData);
dbp.uploadData(roomKey,"ChessmanMoveData",chessmanMoveData);
dbp.uploadData(roomKey,"ChessboardData",chessboardData);
dbp.uploadData(roomKey,"MoveState","black");
// 回合數增加
turn += 1;
dbp.uploadData(roomKey,"Turn",String.valueOf(turn));
}
}
runOnUiThread(() -> {
// 清除上回合所有移動資料
clearData();
});
}).start();
}
判斷遊戲是否結束
public boolean isGameFinish(){
Boolean isGameFinish=false;
// 如果吃的棋是國王則遊戲結束
if(chessboardData.get(playerChessboardData.getStringBoardData(stopChessman)).equals("bK")){
isGameFinish = true;
dbp.uploadData(roomKey,"WinPlayer","white");
// 產生棋譜資料
moveData(String.valueOf(playerChessboardData.getStringBoardData(startChessman))
,String.valueOf(playerChessboardData.getStringBoardData(stopChessman)));
moveData = moveData + " #";
// 修改棋盤資料,將目標格棋子改為原起始格棋子,原起始格棋子改為空格
chessboardData.put(String.valueOf(playerChessboardData.getStringBoardData(stopChessman)),String.valueOf(chessboardData.get(playerChessboardData.getStringBoardData(startChessman))));
chessboardData.put(String.valueOf(playerChessboardData.getStringBoardData(startChessman))," ");
chessmanMoveData.put(String.valueOf(turn),moveData);
dbp.uploadData(roomKey,"ChessmanMoveData",chessmanMoveData);
dbp.uploadData(roomKey,"ChessboardData",chessboardData);
}
return isGameFinish;
}
判斷是否接收到王車易位的指標,若有則同時移動城堡
public void isCastling(){
if(castling.equals("leftCastling")){
chessboardData.put("d1","wR");
chessboardData.put("a1"," ");
}else if(castling.equals("rightCastling")){
chessboardData.put("f1","wR");
chessboardData.put("h1"," ");
}
}
處理士兵的特殊走法
public void disposePawn(){
// 如果可吃過路兵,將對方兵變為空格
if(!(inPassing.equals(""))){
chessboardData.put(inPassing," ");
}
// 將自己的兵標記清除
for(int i=1;i<=8;i++){
pawnMove1.put(coordinate_a[i]+"4",false);
}
// 如果有兵起始走2格,將該兵做標記
if(!(moveTwoStep.equals(""))){
pawnMove1.put(moveTwoStep,true);
}
}
產生棋譜資料
public void moveData(String start,String stop){
// moveData = 棋種 + 起始座標
moveData = chessboardData.get(start).toString().charAt(1) + start;
// 判斷是移動到空格還是吃棋
if(chessboardData.get(stop).equals(" ")){
moveData = moveData + " > ";
} else if (String.valueOf(chessboardData.get(stop).toString().charAt(0)).equals("b")) {
moveData = moveData + " X ";
}
// moveData = 棋種 + 起始座標 X,> 目標座標
moveData = moveData + stop;
}
判斷士兵是否可進行升變,若可以則跳出選擇升變的dialog
public void isPromotion(){
// 判斷是否有兵移動到最底橫列
if(chessboardData.get(String.valueOf(playerChessboardData.getStringBoardData(startChessman))).equals("wP")
&& stopChessman/8==0){
isPromotion = true;
runOnUiThread(new Runnable() {
@Override
public void run() {
// 顯示升變選擇
showPromotionDialog(stopChessman);
}
});
}
}
初始化暫存的變數
public void clearData(){
startChessman = 99;
stopChessman = 99;
castling = "";
moveTwoStep = "";
inPassing = "";
getCount=0;
isPromotion = false;
for(int i=0;i<64;i++){
chessmanSelect.get(i).setBackgroundResource(R.drawable.blank);
}
}
升變是士兵的特殊走法之一,我們在這邊實作簡單的對話框來實現讓使用者選擇欲升變的棋種
public void showPromotionDialog(int p){
// 創建升變Dialog並設置自定義布局
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.white_promotion_dialog_item);
// 獲取自定義布局中的UI元素
TextView tv_q = dialog.findViewById(R.id.tv_q);
TextView tv_b = dialog.findViewById(R.id.tv_b);
TextView tv_n = dialog.findViewById(R.id.tv_n);
TextView tv_r = dialog.findViewById(R.id.tv_r);
Button btn_promotion_q = dialog.findViewById(R.id.btn_promotion_q);
Button btn_promotion_b = dialog.findViewById(R.id.btn_promotion_b);
Button btn_promotion_n = dialog.findViewById(R.id.btn_promotion_n);
Button btn_promotion_r = dialog.findViewById(R.id.btn_promotion_r);
Button btn_submit = dialog.findViewById(R.id.btn_submit);
promotion = "";
btn_submit.setEnabled(false);
btn_submit.setBackgroundResource(R.drawable.whitebackground_grayline);
btn_promotion_q.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tv_q.setBackgroundResource(R.drawable.blank);
tv_b.setBackgroundResource(R.drawable.blank);
tv_n.setBackgroundResource(R.drawable.blank);
tv_r.setBackgroundResource(R.drawable.blank);
if(promotion.equals("Q")){
promotion="";
}else{
promotion="Q";
tv_q.setBackgroundResource(R.drawable.redline);
}
if(promotion.equals("")){
btn_submit.setEnabled(false);
btn_submit.setBackgroundResource(R.drawable.whitebackground_grayline);
}else{
btn_submit.setEnabled(true);
btn_submit.setBackgroundResource(R.drawable.redbackground_blackline);
}
}
});
btn_promotion_b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tv_q.setBackgroundResource(R.drawable.blank);
tv_b.setBackgroundResource(R.drawable.blank);
tv_n.setBackgroundResource(R.drawable.blank);
tv_r.setBackgroundResource(R.drawable.blank);
if(promotion.equals("B")){
promotion="";
}else{
promotion="B";
tv_b.setBackgroundResource(R.drawable.redline);
}
if(promotion.equals("")){
btn_submit.setEnabled(false);
btn_submit.setBackgroundResource(R.drawable.whitebackground_grayline);
}else{
btn_submit.setEnabled(true);
btn_submit.setBackgroundResource(R.drawable.redbackground_blackline);
}
}
});
btn_promotion_n.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tv_q.setBackgroundResource(R.drawable.blank);
tv_b.setBackgroundResource(R.drawable.blank);
tv_n.setBackgroundResource(R.drawable.blank);
tv_r.setBackgroundResource(R.drawable.blank);
if(promotion.equals("N")){
promotion="";
}else{
promotion="N";
tv_n.setBackgroundResource(R.drawable.redline);
}
if(promotion.equals("")){
btn_submit.setEnabled(false);
btn_submit.setBackgroundResource(R.drawable.whitebackground_grayline);
}else{
btn_submit.setEnabled(true);
btn_submit.setBackgroundResource(R.drawable.redbackground_blackline);
}
}
});
btn_promotion_r.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tv_q.setBackgroundResource(R.drawable.blank);
tv_b.setBackgroundResource(R.drawable.blank);
tv_n.setBackgroundResource(R.drawable.blank);
tv_r.setBackgroundResource(R.drawable.blank);
if(promotion.equals("R")){
promotion="";
}else{
promotion="R";
tv_r.setBackgroundResource(R.drawable.redline);
}
if(promotion.equals("")){
btn_submit.setEnabled(false);
btn_submit.setBackgroundResource(R.drawable.whitebackground_grayline);
}else{
btn_submit.setEnabled(true);
btn_submit.setBackgroundResource(R.drawable.redbackground_blackline);
}
}
});
btn_submit.setOnClickListener(v -> {
dialog.dismiss();
moveData = moveData +" ("+promotion+")";
new Thread(() ->{
chessmanMoveData.put(String.valueOf(turn),moveData);
chessboardData.put(playerChessboardData.getStringBoardData(p),"w"+promotion);
dbp.uploadData(roomKey,"ChessboardData",chessboardData);
dbp.uploadData(roomKey,"ChessmanMoveData",chessmanMoveData);
dbp.uploadData(roomKey,"MoveState","black");
// 回合數增加
turn += 1;
dbp.uploadData(roomKey,"Turn",String.valueOf(turn));
}).start();
});
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_gravity="center"
android:background="@drawable/brownbackground_grayline">
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/brownline"
android:gravity="center"
android:text="請選擇一個棋種"
android:textColor="@color/black"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/guideline50"
app:layout_constraintEnd_toStartOf="@+id/guideline94"
app:layout_constraintStart_toStartOf="@+id/guideline92"
app:layout_constraintTop_toTopOf="@+id/guideline135" />
<Button
android:id="@+id/btn_submit"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/redbackground_blackline"
android:gravity="center"
android:text="確定"
android:textColor="@color/white"
android:textStyle="bold"
app:backgroundTint="@null"
app:layout_constraintBottom_toTopOf="@+id/guideline101"
app:layout_constraintEnd_toStartOf="@+id/guideline94"
app:layout_constraintStart_toStartOf="@+id/guideline92"
app:layout_constraintTop_toTopOf="@+id/guideline66" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline50"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.2" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline51"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline66"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.8" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline67"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.2" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline65"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline68"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.8" />
<TextView
android:id="@+id/tv_q"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/guideline51"
app:layout_constraintEnd_toStartOf="@+id/guideline65"
app:layout_constraintStart_toStartOf="@+id/guideline67"
app:layout_constraintTop_toTopOf="@+id/guideline50" />
<TextView
android:id="@+id/tv_b"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/guideline51"
app:layout_constraintEnd_toStartOf="@+id/guideline68"
app:layout_constraintStart_toStartOf="@+id/guideline65"
app:layout_constraintTop_toTopOf="@+id/guideline50" />
<TextView
android:id="@+id/tv_n"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/guideline66"
app:layout_constraintEnd_toStartOf="@+id/guideline65"
app:layout_constraintStart_toStartOf="@+id/guideline67"
app:layout_constraintTop_toTopOf="@+id/guideline51" />
<TextView
android:id="@+id/tv_r"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/guideline66"
app:layout_constraintEnd_toStartOf="@+id/guideline68"
app:layout_constraintStart_toStartOf="@+id/guideline65"
app:layout_constraintTop_toTopOf="@+id/guideline51" />
<Button
android:id="@+id/btn_promotion_q"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/white_queen"
app:backgroundTint="@null"
app:layout_constraintBottom_toTopOf="@+id/guideline51"
app:layout_constraintEnd_toStartOf="@+id/guideline65"
app:layout_constraintStart_toStartOf="@+id/guideline67"
app:layout_constraintTop_toTopOf="@+id/guideline50" />
<Button
android:id="@+id/btn_promotion_b"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/white_bishop"
app:backgroundTint="@null"
app:layout_constraintBottom_toTopOf="@+id/guideline51"
app:layout_constraintEnd_toStartOf="@+id/guideline68"
app:layout_constraintStart_toStartOf="@+id/guideline65"
app:layout_constraintTop_toTopOf="@+id/guideline50" />
<Button
android:id="@+id/btn_promotion_n"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/white_knight"
app:backgroundTint="@null"
app:layout_constraintBottom_toTopOf="@+id/guideline66"
app:layout_constraintEnd_toStartOf="@+id/guideline65"
app:layout_constraintStart_toStartOf="@+id/guideline67"
app:layout_constraintTop_toTopOf="@+id/guideline51" />
<Button
android:id="@+id/btn_promotion_r"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/white_rook"
app:backgroundTint="@null"
app:layout_constraintBottom_toTopOf="@+id/guideline66"
app:layout_constraintEnd_toStartOf="@+id/guideline68"
app:layout_constraintStart_toStartOf="@+id/guideline65"
app:layout_constraintTop_toTopOf="@+id/guideline51" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline92"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.1" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline94"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.9" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline101"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.97" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline135"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.03" />
</androidx.constraintlayout.widget.ConstraintLayout>
成果:
至此,整個主程式就算是大功告成,下一篇開始我們來實作設置(setting)這個額外功能